package com.nxzh.de.executor.config.datasource;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.nxzh.de.executor.common.constant.Constants;
import com.nxzh.de.executor.common.core.redis.RedisCache;
import com.nxzh.de.executor.common.utils.StringUtils;
import com.nxzh.de.executor.common.utils.reflect.ReflectUtils;
import com.nxzh.de.executor.config.DruidConfig;
import com.nxzh.de.executor.config.MyBatisConfig;
import com.nxzh.de.executor.config.properties.DruidProperties;
import com.nxzh.de.executor.config.datasource.transaction.CustomSqlSessionTemplate;
import com.nxzh.de.executor.domain.SysSourceConfig;
import com.nxzh.de.executor.service.ISysSourceConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * jierui Atomikos
 */
@Configuration
@Slf4j
public class DynamicDataSourceConfig {

    @Autowired
    private ISysSourceConfigService iSysSourceConfigService;

    @Autowired
    private CustomSqlSessionTemplate customSqlSessionTemplate;

    @Autowired
    private MyBatisConfig myBatisConfig;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private DruidProperties druidProperties;

    @Resource(name = "dynamicDataSource")
    DynamicDataSource dynamicDataSource;

    @PostConstruct
    public void init() {

        log.info("@@@@系统数据源初始化");
        Map<Object, SqlSessionFactory> targetSqlSessionFactories = new HashMap<>();
        Map<Object, Object> targetDataSources = new HashMap<>();

        List<SysSourceConfig> sysSourceConfigs = iSysSourceConfigService.selectSysSourceConfigList(new SysSourceConfig());
        for (SysSourceConfig sysSourceConfig : sysSourceConfigs) {
            DruidXADataSource dynamicDataSource = new DruidXADataSource();
            dynamicDataSource.setDriverClassName(sysSourceConfig.getDrivers());
            dynamicDataSource.setUrl(sysSourceConfig.getUrl());
            dynamicDataSource.setUsername(sysSourceConfig.getUserName());

            if (StringUtils.isNotEmpty(sysSourceConfig.getPassWord())) {
                dynamicDataSource.setPassword(sysSourceConfig.getPassWord());
            }

            try {
//                DruidProperties druidProperties= SpringUtils.getBean("druidProperties");

                DataSource xaDataSource = DruidConfig.getXaDataSource(druidProperties.dataSource(dynamicDataSource), sysSourceConfig.getSourceCode());
                targetDataSources.put(sysSourceConfig.getSourceCode(),xaDataSource);
                targetSqlSessionFactories.put(sysSourceConfig.getSourceCode(), myBatisConfig.createSqlSessionFactory(xaDataSource));

                //将数据源遍历放到redis中
                String pageKey = Constants.DATA_SOURCE_KEY + sysSourceConfig.getPackageName();
                redisCache.getAndSetCacheObject(pageKey, sysSourceConfig.getSourceCode());

            } catch (Exception e) {
                log.error("@@@@系统数据源配置加载异常，相关数据源：{},异常信息:{}", sysSourceConfig.getSourceCode(), e.getMessage(), e);
            }
            log.info("@@@@系统数据源配置信息加载初始化,加载数据源：{}", sysSourceConfig.getSourceCode());
        }

        if (MapUtils.isNotEmpty(targetSqlSessionFactories)) {
            //将动态添加的数据源增加到spring动态数据源中
            dynamicDataSource.putTargetDataSources(targetDataSources);

            targetSqlSessionFactories.putAll(ReflectUtils.getFieldValue(customSqlSessionTemplate, "targetSqlSessionFactories"));
            customSqlSessionTemplate.setTargetSqlSessionFactories(targetSqlSessionFactories);
        }

    }

}
